<?php
namespace App\Logic\SalesReport;

use App\Models\Basics\AmazonAccount;
use App\Models\Basics\AmazonCountry;
use App\Models\Basics\SysCountry;
use App\Models\Basics\ExchangeRate;
use App\Models\Basics\SysICountry;
use App\Models\MonthlyReport\Payment\PaymentCPlanFee;
use App\Models\Product\ProductAmazonSku;
use App\Models\MonthlyReport\Payment\AdsDSP;
use App\Models\MonthlyReport\Payment\AdsMonthly;
use App\Models\MonthlyReport\Payment\AdsTH;
use App\Models\MonthlyReport\Payment\AdsVBC;
use App\Models\MonthlyReport\Payment\InventoryEvent;
use App\Models\MonthlyReport\Payment\LongTermStorage;
use App\Models\MonthlyReport\Payment\MonthlyStorage;
use App\Models\MonthlyReport\Cost\LogisticsBasics;
use App\Models\MonthlyReportCommon\Cost\PriceBasics;
use App\Models\MonthlyReport\Payment\PaymentIcFee;
use App\Models\MonthlyReport\Payment\PaymentRebates;
use App\Models\MonthlyReport\Payment\PaymentReFee;
use App\Models\MonthlyReport\Payment\PaymentSales;
use App\Models\MonthlyReport\Payment\PaymentThFee;
use App\Models\MonthlyReport\Payment\PaymentTotal;
use App\Models\MonthlyReport\Payment\RemovalOrder;
use App\Models\Reimburse\ReimburseDetail;
use App\Models\SalesReport\PaymentDetail as TPaymentDetail;
use Illuminate\Support\Facades\DB;

class PaymentDetail
{
    public static function exePayment($date){
        try{
            $start = time();
            $start_memory = memory_get_usage();
            $monthlyStorage = [];
            $purchasePrice = [];
            $shipmentPrice = [];
            $area = [];
            $rate = [];
            $account = [];
            ProductAmazonSku::query()
                ->orderBy('id')
                ->chunk(500, function ($pass) use (&$account,&$area,&$rate,&$monthlyStorage,&$purchasePrice,&$shipmentPrice,$date){
                    DB::beginTransaction();
                    $paymentDetails = [];
                    foreach ($pass as $pas){
                        $where = [
                            ['report_date',$date],
                            ['seller_sku',$pas->seller_sku],
                            ['country_id',$pas->country_id],
                            ['is_common',0]
                        ];
                        $paymentDetail = [];
                        $paymentDetail['account_id'] = $pas->account_id;
                        if(!array_key_exists($pas->country_id,$area)){
                            $area[$pas->country_id] = SysICountry::getAreaIdByCountryId($pas->country_id);
                        }
                        $paymentDetail['area_id'] = $area[$pas->country_id];
                        $paymentDetail['seller_id'] = $pas->seller_id;
                        $paymentDetail['psku_id'] = $pas->psku_id;
                        //汇率
                        if(!array_key_exists($pas->country_id,$rate)){
                            $currencyCode = AmazonCountry::getCurrencyCodeByCountryId($pas->country_id);
                            $rate[$pas->country_id] = ExchangeRate::getRateOddsToRMB($currencyCode,strtotime($date));
                        }
                        $rateOdds = $rate[$pas->country_id];
                        $paymentDetail['rate_odds'] = $rateOdds;

                        //采购价格
                        $priceKey = $pas->psku_id.'-'.$date;
                        if(!array_key_exists($priceKey,$purchasePrice)){
                            $purchasePrice[$priceKey] = PriceBasics::getPrice($pas->psku_id,$date);
                        }
                        $purchasePriceRMB = $purchasePrice[$priceKey];

                        //物流运输价格
                        $lPriceKey = $paymentDetail['area_id'].'-'.$pas->psku_id.'-'.$date;
                        if(!array_key_exists($lPriceKey,$shipmentPrice)){
                            $shipmentPrice[$lPriceKey] = LogisticsBasics::getLogistics($paymentDetail['area_id'],$pas->psku_id,$date);
                        }
                        $shipmentPriceRMB = $shipmentPrice[$lPriceKey];
                        $paymentDetail['purchase_price_rmb'] = $purchasePriceRMB;
                        $paymentDetail['shipment_price_rmb'] = $shipmentPriceRMB;

                        //Amazon月仓储费
                        $accountKey = $pas->account_id.'_'.$pas->country_id;
                        if(!array_key_exists($accountKey,$account)){
                            $account[$accountKey] = self::__getAccount($pas->account_id,$pas->country_id);
                        }
                        $_account = $account[$accountKey];
                        $value = $_account.'_'.$pas->country_id.'_'.$pas->child_asin.'_'.$pas->fnsku;
                        if(!in_array($value,$monthlyStorage)){
                            $monthlyStorage[] = $value;
                            $paymentDetail['ms_fee'] = self::_getMonthlyStorage($date,$_account,$pas->country_id,$pas->child_asin,$pas->fnsku);
                        }else{
                            $paymentDetail['ms_fee'] = 0;
                        }
                        $paymentDetail['ms_fee_rmb'] = round($paymentDetail['ms_fee'] * $rateOdds,4);

                        $paymentDetail['lts_fee'] = self::_getLongTermStorage($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['lts_fee_rmb'] = round($paymentDetail['lts_fee'] * $rateOdds,3);
                        $paymentDetail['rm_fee'] = self::_getRemovalOrder($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['rm_fee_rmb'] = round($paymentDetail['rm_fee'] * $rateOdds,3);
                        $paymentDetail['spend'] = self::_getSpend($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['spend_rmb'] = round($paymentDetail['spend'] * $rateOdds,3);
                        $paymentDetail['reimburse_rmb'] = self::_getReimburseRMB($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['reimburse_os_rmb'] = self::_getOperatingServiceRMB($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['reimburse_profit_rmb'] = self::_getReimburseProfitRMB($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['ied_rmb'] = self::_getReturnSales($date,$pas->country_id,$pas->seller_sku,$purchasePriceRMB,$shipmentPriceRMB);
                        $paymentDetail['rod_rmb'] = self::_getRODestruction($date,$pas->country_id,$pas->seller_sku,$purchasePriceRMB,$shipmentPriceRMB);
                        $pSales = self::_getPaymentSales($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['sales_volume'] = $pSales->quantity ?? 0;
                        $paymentDetail['sales_amount'] = $pSales->sales ?? 0;
                        $paymentDetail['sales_amount_rmb'] = round($paymentDetail['sales_amount'] * $rateOdds,3);
                        $paymentDetail['selling_fees'] = $pSales->selling_fees ?? 0;
                        $paymentDetail['selling_fees_rmb'] = round($paymentDetail['selling_fees'] * $rateOdds,3);
                        $paymentDetail['fba_fees'] = $pSales->fba_fees ?? 0;
                        $paymentDetail['fba_fees_rmb'] = round($paymentDetail['fba_fees'] * $rateOdds,3);
                        $pRefee = self::_getPaymentReFee($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['refund_num'] = $pRefee->quantity ?? 0;
                        $paymentDetail['refund_amount'] = $pRefee->total ?? 0;
                        $paymentDetail['refund_amount_rmb'] = round($paymentDetail['refund_amount'] * $rateOdds,3);
                        $pThfee = self::_getPaymentThFee($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['p_thfba'] = $pThfee->total ?? 0;
                        $paymentDetail['p_thfba_rmb'] = round($paymentDetail['p_thfba'] * $rateOdds,3);
                        $pIcfee = self::_getPaymentIcFee($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['p_icfee'] = $pIcfee->total ?? 0;
                        $paymentDetail['p_icfee_rmb'] = round($paymentDetail['p_icfee'] * $rateOdds,3);
                        $pIcfee = self::_getPaymentRebates($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['rebates'] = $pIcfee->rebates ?? 0;
                        $paymentDetail['rebates_rmb'] = round($paymentDetail['rebates'] * $rateOdds,3);
                        $pCPlanFee = self::_getPaymentCPlanFee($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['cplan_fee'] = $pCPlanFee->cplan_fee ?? 0;
                        $paymentDetail['cplan_fee_rmb'] = round($paymentDetail['cplan_fee'] * $rateOdds,3);
                        $pt = self::_getPaymentTotal($date,$pas->country_id,$pas->seller_sku);
                        $paymentDetail['total'] = $pt->total ?? 0;
                        $paymentDetail['total_rmb'] = round($paymentDetail['total'] * $rateOdds,3);
                        $paymentDetail['t_purchase_price_rmb'] = round($paymentDetail['sales_volume'] * $paymentDetail['purchase_price_rmb'],3);
                        $paymentDetail['t_shipment_price_rmb'] = round($paymentDetail['sales_volume'] * $paymentDetail['shipment_price_rmb'],3);
                        $paymentDetail['profit_rmb'] = round($paymentDetail['sales_amount_rmb'] +
                            $paymentDetail['ied_rmb'] -
                            $paymentDetail['t_purchase_price_rmb'] -
                            $paymentDetail['t_shipment_price_rmb'] +
                            $paymentDetail['refund_amount_rmb'] +
                            $paymentDetail['selling_fees_rmb'] +
                            $paymentDetail['fba_fees_rmb'] +
                            $paymentDetail['p_thfba_rmb'] -
                            $paymentDetail['ms_fee_rmb'] -
                            $paymentDetail['lts_fee_rmb'] +
                            $paymentDetail['p_icfee_rmb'] -
                            $paymentDetail['rm_fee_rmb'] +
                            $paymentDetail['rebates_rmb'] -
                            $paymentDetail['spend_rmb'] -
                            $paymentDetail['reimburse_rmb'] -
                            $paymentDetail['reimburse_os_rmb'] -
                            $paymentDetail['reimburse_profit_rmb'] +
                            $paymentDetail['cplan_fee_rmb'] -
                            $paymentDetail['rod_rmb'],3);
                        $paymentDetail['earning_rmb'] = round($paymentDetail['t_purchase_price_rmb'] +
                            $paymentDetail['t_shipment_price_rmb'] +
                            $paymentDetail['profit_rmb'],3);
                        $count = TPaymentDetail::query()->where($where)->count();
                        if($count > 0){
                            TPaymentDetail::query()->where($where)->update($paymentDetail);
                        }else{
                            $paymentDetail['report_date'] = $date;
                            $paymentDetail['seller_sku'] = $pas->seller_sku;
                            $paymentDetail['country_id'] = $pas->country_id;
                            $paymentDetail['is_common'] = 0;
                            $paymentDetails[] = $paymentDetail;
                        }
                    }
                    if(!empty($paymentDetails)){
                        DB::table('sr_payment_detail')->insert($paymentDetails);
                    }
                    DB::commit();
                });
            $end = time();
            $end_memory = memory_get_usage();
            print_r(($end - $start).'--------'.(($end_memory - $start_memory)/1024/1024)) ;
        }catch (\Exception $e){
            report($e);
        }
    }

    //销量、销售额、佣金、FBA交易费
    private static function _getPaymentSales($date,$countryId,$sellerSku){
        return PaymentSales::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('seller_sku',$sellerSku)
            ->first();
    }

    //退货量、退货费
    private static function _getPaymentReFee($date,$countryId,$sellerSku){
        return PaymentReFee::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('seller_sku',$sellerSku)
            ->first();
    }

    //第三方FBA发货费
    private static function _getPaymentThFee($date,$countryId,$sellerSku){
        return PaymentThFee::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('seller_sku',$sellerSku)
            ->first();
    }

    private static function __getAccount($accountId,$countryId){
        $_account = AmazonAccount::getAccountById($accountId);
        if($_account){
            $pos = strripos($_account,'-');
            if(!$pos){
                $account = '';
            }else{
                $prefix = substr($_account,0,$pos);
                $country = SysCountry::getCountryById($countryId);
                $account = $prefix.'-'.$country;
            }
        }else{
            $account = '';
        }
        return $account;
    }

    //Amazon月仓储费
    private static function _getMonthlyStorage($date,$account,$countryId,$asin,$fnsku){
        $monthlyStorage = MonthlyStorage::where('report_date',$date)
            ->where('account',$account)
            ->where('country_id',$countryId)
            ->where('asin',$asin)
            ->where('fnsku',$fnsku)
            ->sum('estimated_monthly_storage_fee');
        return $monthlyStorage ?: 0;
    }

    //Amazon长期仓储费
    private static function _getLongTermStorage($date,$countryId,$sellerSku){
        $longTermStorage = LongTermStorage::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('sku',$sellerSku)
            ->sum('storage_fee');
        return $longTermStorage ?: 0;
    }

    //库存补偿费
    private static function _getPaymentIcFee($date,$countryId,$sellerSku){
        return PaymentIcFee::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->first();
    }

    //移除费用
    private static function _getRemovalOrder($date,$countryId,$sellerSku){
        $removalOrder = RemovalOrder::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('sku',$sellerSku)
            ->sum('removal_fee');
        return $removalOrder ?: 0;
    }

    //促销费
    private static function _getPaymentRebates($date,$countryId,$sellerSku){
        return PaymentRebates::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->first();
    }

    //广告费
    public static function _getSpend($date,$countryId,$sellerSku){
        $adsMonthly = AdsMonthly::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->value('spend');
        $adsVbc = AdsVBC::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->value('spend');
        $adsTh = AdsTH::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->value('spend');
        $adsDSP = AdsDSP::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->value('spend');
        //UK不需要扣税了
//        $spend = (($adsMonthly ?: 0) + ($adsVbc ?: 0) + ($adsTh ?: 0) + ($adsDSP ?: 0)) * ($countryId == 3 ? 1.2 : 1);
        $spend = ($adsMonthly ?: 0) + ($adsVbc ?: 0) + ($adsTh ?: 0) + ($adsDSP ?: 0);
        return round($spend,3);
    }

    //刷单RMB
    private static function _getReimburseRMB($date,$countryId,$sellerSku){
        return ReimburseDetail::where('fee_type',1)->where('paid_status',3)->where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->sum('amount_rmb');
    }

    //运营服务费RMB
    private static function _getOperatingServiceRMB($date,$countryId,$sellerSku){
        return ReimburseDetail::where('fee_type','<>',1)->where('paid_status',3)->where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->sum('amount_rmb');
    }

    //刷单毛利扣减RMB
    private static function _getReimburseProfitRMB($date,$countryId,$sellerSku){
        $rd = ReimburseDetail::select(DB::raw('sum(r_amount * r_rate_odds - purchase_price_rmb - shipment_price_rmb) as amount_rmb'))
            ->where('fee_type',1)
            ->where('paid_status',3)
            ->where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('seller_sku',$sellerSku)
            ->value('amount_rmb');
        return $rd ?: 0;
    }

    //退货二次销售RMB
    private static function _getReturnSales($date,$countryId,$sellerSku,$purchasePriceRMB,$shipmentPriceRMB){
        $quantity = InventoryEvent::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('sku',$sellerSku)
            ->sum('quantity');
        return round(($quantity ?: 0) * ($purchasePriceRMB + $shipmentPriceRMB),3);
    }

    //销毁货物损失RMB
    private static function _getRODestruction($date,$countryId,$sellerSku,$purchasePriceRMB,$shipmentPriceRMB){
        $quantity = RemovalOrder::where('report_date',$date)
            ->where('country_id',$countryId)
            ->where('sku',$sellerSku)
            ->where('disposition','Sellable')
            ->sum('disposed_quantity');
        return round(($quantity ?: 0) * ($purchasePriceRMB + $shipmentPriceRMB),3);
    }
    //清库计划费用
    private static function _getPaymentCPlanFee($date,$countryId,$sellerSku){
        return PaymentCPlanFee::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->first();
    }

    //Total
    private static function _getPaymentTotal($date,$countryId,$sellerSku){
        return PaymentTotal::where('report_date',$date)->where('country_id',$countryId)->where('seller_sku',$sellerSku)->first();
    }
}
